import java.awt.Color;
import java.util.*;

public class Territory extends Observable{

    private boolean Valid;
    private boolean Updated;
    private ArrayList<Player> Attacker;
    private int x, y, FoodUnit, TechnologyUnit; 
    private Player Owner;
    
    private ArrayList<ArrayList<Troop>> TroopList;    

    public Territory(int _x, int _y){
    	x = _x;
    	y = _y;
    	Valid = true;
    	TroopList = new ArrayList<ArrayList<Troop>>(); 
    	for (int i = 0; i < 6; i++){
             ArrayList<Troop> temp = new ArrayList<Troop>();
             TroopList.add(temp);
    	}
          for (int i = 0; i < (x + y); i++)
             addTroop(new Troop(0, false));
          Updated = false;
          Attacker = new ArrayList<Player>();
          FoodUnit = x;
          TechnologyUnit = y;
          Owner = new Player("Tester" + String.valueOf(x) + String.valueOf(y), "123456", Color.green);
    	
    }
    public Territory(int _x, int _y, boolean _Valid, int _TroopAmount, 
    		         Player _Owner, int _FoodUnit, int _TechnologyUnit){
        x = _x;
        y = _y;
        Valid = _Valid;
        TroopList = new ArrayList<ArrayList<Troop>>(); 
    	for (int i = 0; i < 6; i++){
             ArrayList<Troop> temp = new ArrayList<Troop>();
             TroopList.add(temp);
    	}
        for (int i = 0; i < _TroopAmount; i++)
           addTroop(new Troop(0, false));
        Owner = _Owner;
        Updated = false;
        Attacker = new ArrayList<Player>();
        FoodUnit = _FoodUnit;
        TechnologyUnit = _TechnologyUnit;
    }

    public void measurementsChanged(boolean ownerChanged){
    	setChanged();
    	notifyObservers(ownerChanged);// push method
    }
    
    public void updateTerritory(Territory t){
    	for (ArrayList<Troop> list : TroopList){
    		list.clear();
    		int i = TroopList.indexOf(list);
    		for (Troop tr: t.getTroopList(i))
    			list.add(tr);
    	}
    	if (t.getOwner() != Owner){
    		measurementsChanged(true);
            deleteObserver(Owner);
            addObserver(t.getOwner());
            Owner = t.getOwner();
            measurementsChanged(true);
    	}
    	else measurementsChanged(false);
     }
    
    public boolean getValid(){return Valid;}
    public boolean getUpdated(){return Updated;}
    public void setUpdated(boolean b){Updated = b;}
    
    public ArrayList<ArrayList<Troop>> getTroopList() {return TroopList;}
    public ArrayList<Troop> getTroopList(int index){return TroopList.get(index);}
    public int getTroopAmount(){
    	int TroopAmount = 0;
    	for (ArrayList<Troop> list : TroopList)
    		TroopAmount += list.size();
    	return TroopAmount;
    }
    public int getTroopAmount(int index){return TroopList.get(index).size();}
    
    public int getUsableTroopAmount(int index){
    	int total = 0;
    	for (Troop tr: TroopList.get(index))
    		if (tr.getActioned() == false) 
    			total ++;
    	return total;
    	
    }
    
    public void addTroop(Troop tr){
    	int n = tr.getType();
    	TroopList.get(n).add(tr);
    }
    public void removeTroop(int index){
    	TroopList.get(index).remove(0);
    }
    public Troop peekTroop(int index){
    	return TroopList.get(index).get(0);
    }
    
    public void upgradeTroop(int source, int destination, int amount){
    	for (int i = 0; i < amount; i++){
    	Troop tr = peekTroop(source);
    	removeTroop(source);
    	tr.setType(destination);
    	addTroop(tr);
    	}
    }
    
    public Player getOwner(){return Owner;}
    public void setOwner(Player p){Owner = p;}

    public int getx(){return x;}
    public int gety(){return y;}
    public String getLocation(){
    	return "(" + String.valueOf(x) + " ," + String.valueOf(y) + ") ";
    }
    public int getFoodUnit(){return FoodUnit;}
    public int getTechnologyUnit(){return TechnologyUnit;}
 
    public ArrayList<Player> getAttacker(){return Attacker;}
    public void clearAttacker(){Attacker.clear();}
    public void addAttacker(Player p){Attacker.add(p);}

    public boolean CheckNeighbor(Territory neighbor){
        if (!neighbor.getValid()) return false;
    	if (Math.abs(neighbor.getx() - x) > 1) return false;
        if (Math.abs(neighbor.gety() - y) > 1) return false;
        return true;
    }
     
    
}
